<?php

defined("_ARKN_EXEC") or exit("no no, mr. superman no here");

require_once ROOT_FOLDER . "/php/configs/database_cfg.php";

class Authenticator {

	private $db;
	private $isDbConnected;
	private $logger;	

	public function __construct() {
		$this->logger = Logger::getLogger("Login.php");
		$this->db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
		if($this->db->connect_error)
			throw new Exception("Database connection error");			
	}

	public function login($username, $password) {
		$this->logger->info("Login.login enter.");
		$this->logger->info("Username is $username and password is $password");
		$succes = FALSE;
		if($stmt = $this->db->prepare("select accountid, firstname, lastname, roleid, pword, salt, lastattempt, failedattempts from accounts where username = ?")) {
			$stmt->bind_param("s", $username);
			$stmt->execute();
			$stmt->store_result();
			if(!$stmt->errno) {
				if($stmt->num_rows == 1) {
					$stmt->bind_result($accountid, $firstname, $lastname, $roleid, $pword, $salt, $lastAttempt, $failedAttempts);
					$stmt->fetch();
					$stmt->close();
					if(($failedAttempts < 3) || $this->authDelayed($lastAttempt)) {
						$passHash = hash("sha512", $salt . $password);
						if($passHash == $pword) {
							$this->logger->info("Authentication is successful.");
							$_SESSION["roleid"] = $roleid;
							$_SESSION["accountid"] = $accountid;
							$_SESSION["name"] = $firstname . " " . $lastname;
							if($stmt = $this->db->prepare("update accounts set failedAttempts = 0 where username = ?;")) {
								$stmt->bind_param("s", $username);
								$stmt->execute();
								$stmt->close();
							}							
							$succes = TRUE;
						} else {
							$this->logger->info("Authentication is NOT successful - password is incorrect.");
							if($stmt = $this->db->prepare("update accounts set failedAttempts = ?, lastAttempt = ? where username = ?;")) {
								$now = new DateTime();
								$formattedNow = $now->format('Y-m-d H:i:s');
								$failedAttempts++;
								$stmt->bind_param("iss", $failedAttempts, $formattedNow, $username);
								$stmt->execute();
								$stmt->close();
							}
						}
					} else {
						$this->logger->info("Authentication is NOT successful - too many failed login attempts.");
						if($stmt = $this->db->prepare("update accounts set lastAttempt = ? where username = ?;")) {
							$now = new DateTime();
							$stmt->bind_param("ss", $now->format('Y-m-d H:i:s'), $username);
							$stmt->execute();
							$stmt->close();
						}
					}
				} else 
					$this->logger->error("Authentication is NOT successful - username not found.");
			} else
				$this->logger->error("Error occured during authentication.");
		}
		$this->logger->info("Login.login exit.");
		return $succes;
	}

	function authDelayed($time) {
		if(empty($time)) {
			$this->logger->info("gay");
			return FALSE;
		} else {
			$dateTime = new DateTime($time);
			$dateTime->add(new DateInterval("PT5M"));
			$now = new DateTime();
			$this->logger->info("gay");
			$this->logger->info($dateTime);
			$this->logger->info($now);
			if($dateTime < $now)
				return TRUE;
			return FALSE;
		}
	}

	public function __destruct() {
		if($this->db != NULL) {
			$this->db->kill($this->db->thread_id);
			$this->db->close();
		}		
	}
}

$authenticator = new Authenticator();
?>
